/*
 *
 *   Copyright (C) 2005 by Raymond Huang
 *   plushuang at users.sourceforge.net
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of portions of this program with the
 *  OpenSSL library under certain conditions as described in each
 *  individual source file, and distribute linked combinations
 *  including the two.
 *  You must obey the GNU Lesser General Public License in all respects
 *  for all of the code used other than OpenSSL.  If you modify
 *  file(s) with this exception, you may extend this exception to your
 *  version of the file(s), but you are not obligated to do so.  If you
 *  do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source
 *  files in the program, then also delete it here.
 *
 */

#include <stdio.h>
#include <urlglib/msg_client.h>

#ifdef _WIN32
// Windowns version --------------------------------------------------
#include <winsock.h>

static SOCKET msg_client_connect ()
{
	SOCKET fd;
	struct sockaddr_in saddr;
//	int  error;

	fd = socket (AF_INET, SOCK_STREAM, 0);
//	error = WSAGetLastError();
	if (fd == INVALID_SOCKET)
		return INVALID_SOCKET;

	saddr.sin_family = AF_INET;
	saddr.sin_port = htons (URLGFE_SOCKET_PORT);
	saddr.sin_addr.S_un.S_addr = inet_addr ("127.0.0.1");

	if (connect (fd, (struct sockaddr *) &saddr, sizeof(saddr)) == SOCKET_ERROR) {
		closesocket (fd);
		return INVALID_SOCKET;
	}
	return fd;
}

void   msg_client_free (SOCKET fd)
{
	closesocket (fd);
}

#else
// Unix version ------------------------------------------------------
#include <sys/socket.h>    // socket api
#include <unistd.h>        // uid_t and others
#include <errno.h>

#define INVALID_SOCKET  (-1)

static SOCKET msg_client_connect ()
{
	SOCKET fd;
	uid_t stored_uid, euid;
	struct sockaddr_un saddr;

	fd = socket (AF_UNIX, SOCK_STREAM, 0);
	if (fd <= 0)
		return INVALID_SOCKET;

	saddr.sun_family = AF_UNIX;
	stored_uid = getuid();
	euid = geteuid();
	setuid(euid);
	sprintf (saddr.sun_path, "%s/%s_%s",
	         g_get_tmp_dir (), URLGFE_SOCKET_NAME, g_get_user_name ());
	setreuid(stored_uid, euid);

	if (connect (fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
		close (fd);
		return INVALID_SOCKET;
	}
	return fd;
}

void   msg_client_free (SOCKET fd)
{
	close (fd);
}

#endif

// common ------------------------------------------------------------

gboolean msg_client_ack ()
{
	SOCKET fd;
	struct MsgPacket  packet;
	gboolean result = FALSE;

	fd = msg_client_connect ();

	if (fd == INVALID_SOCKET)
		return FALSE;

	packet.type = MESSAGE_ACK;
	packet.length = 0;
	if (send (fd, (char*) &packet, sizeof (packet), 0) == sizeof (packet) &&
	    recv (fd, (char*) &packet, sizeof (packet), 0) == sizeof (packet) )
	{
		if (packet.type == MESSAGE_ACK)
			result = TRUE;
	}

	msg_client_free (fd);
	return result;
}

gboolean  msg_client_add_url (const gchar* url)
{
	SOCKET fd;
	struct MsgPacket  packet;
	gboolean result = FALSE;

	fd = msg_client_connect ();

	if (fd < 0)
		return FALSE;

	packet.type = MESSAGE_ADD;
	packet.length = strlen (url);
	if (send (fd, (char*) &packet, sizeof (packet), 0) == sizeof (packet) &&
	    send (fd, url, packet.length, 0) == packet.length )
	{
		result = TRUE;
	}

	msg_client_free (fd);
	return result;
}
